// Async Await is a fucking joke
// We can't use aynsc await during the start up because you can't wrap that output call
// as a async await ... on and on and on
// so we need to do this in two steps
// if we find a keys file, great, read it and store it
// if not then wait until inside the init-middleware and call the rsaPemKeys there
const _ = require('lodash')
const fsx = require('fs-extra')
const { jwtProcessKey } = require('./options')
const { isObjectHasKey } = require('jsonql-utils')
const { isString } = require('jsonql-params-validator')
const debug = require('debug')('jsonql-koa:process-jwt-keys')

/**
 * Get the keys from cache call
 * @param {object} ctx koa context
 * @param {object} config configuration
 * @return {mixed} boolean on failed or object on success
 */
const getKeysFromCache = (ctx, config) => {
  const { setter, getter } = ctx.state.jsonql;
  if (config.enableAuth &&
      config.useJwt &&
      !isString(config.useJwt) &&
      (!config.publicKey || !config.privateKey)) {
    let privateKey = getter('privateKey')
    let publicKey = getter('publicKey')
    if (privateKey && publicKey) {
      return _.extend(config, { publicKey, privateKey })
    }
  }
  return false;
}

/**
 * Get the keys from the init promise call
 * @param {object} ctx koa context
 * @param {object} config configuration
 * @return {mixed} boolean on failed or object on success
 */
const getCreatedKeys = (ctx, config) => {
  if (isObjectHasKey(config, jwtProcessKey) && config[jwtProcessKey].then) {
    const { setter } = ctx.state.jsonql;
    return config[jwtProcessKey]
      .then( result => _.extend( config, _.mapValues(result, value => fsx.readFileSync(value) ) ) )
      .then(keys => {
        _.forEach(keys, (value, key) => {
          setter(key, value)
        })
        return keys;
      })
  }
  return false;
}

/**
 * we only call this here to init it
 * @param {object} ctx koa context
 * @param {object} config configuration
 * @return {object} config with the privateKey and publicKey stored
 */
module.exports = function processJwtKeys(ctx, config) {
  let result;
  if ((result = getKeysFromCache(ctx, config)) !== false) {
    return result;
  }
  if ((result = getCreatedKeys(ctx, config)) !== false) {
    return result;
  }
  return config;
}
